public class Equivalence {

    public static void test(int value) {
        Integer n1 = value;
        Integer n2 = value;
        System.out.printf("Integer %d:\n", value);
        System.out.printf("n1 == n2: %b\n", n1 == n2);
        System.out.printf("n1.equals(n2): %b\n\n", n1.equals(n2));

        Integer newN1 = new Integer(value);
        Integer newN2 = new Integer(value);
        System.out.printf("new Integer %d:\n", value);
        System.out.printf("newN1 == newN2: %b\n", newN1 == newN2);
        System.out.printf("newN1.equals(newN2): %b\n\n", newN1.equals(newN2));

        Integer v1 = Integer.valueOf(value);
        Integer v2 = Integer.valueOf(value);
        System.out.printf("Integer.valueOf %d:\n", value);
        System.out.printf("v1 == v2: %b\n", v1 == v2);
        System.out.printf("v1.equals(v2): %b\n\n", v1.equals(v2));

        int x = value;
        int y = value;
        System.out.printf("int %d:\n", value);
        System.out.printf("x == y: %b\n", x == y);
        // System.out.printf("x.equals(y): %b\n", x.equals(y)); // This will not compile
    }

    public static void main(String[] args) {
        test(127);
        System.out.println("---------------------");
        test(128);
    }
}

/*
Integer 127:
n1 == n2: true
n1.equals(n2): true

new Integer 127:
newN1 == newN2: false
newN1.equals(newN2): true

Integer.valueOf 127:
v1 == v2: true
v1.equals(v2): true

int 127:
x == y: true
---------------------
Integer 128:
n1 == n2: false
n1.equals(n2): true

new Integer 128:
newN1 == newN2: false
newN1.equals(newN2): true

Integer.valueOf 128:
v1 == v2: false
v1.equals(v2): true

int 128:
x == y: true

 */

/*
Integer n1 = value;
n1 == n2 和 n1.equals(n2)
当 value 在 -128 到 127 范围内时（如 127），Integer n1 = value; 和 Integer n2 = value; 使用了自动装箱机制，并且由于 JVM 的缓存优化，n1 == n2 返回 true（引用相同）。
当 value 超出该范围（如 128），n1 == n2 返回 false（引用不同），但 n1.equals(n2) 始终返回 true（值相等）。

Integer newN1 = new Integer(value);
newN1 == newN2 和 newN1.equals(newN2)
使用 new Integer(value) 创建的对象总是不同的实例，因此 newN1 == newN2 返回 false。
但 newN1.equals(newN2) 始终返回 true（值相等）。

Integer v1 = Integer.valueOf(value);
v1 == v2 和 v1.equals(v2)
使用 Integer.valueOf(value) 创建的对象会利用 JVM 的缓存机制：
如果 value 在 -128 到 127 范围内，v1 == v2 返回 true（引用相同）。
如果超出范围，v1 == v2 返回 false（引用不同），但 v1.equals(v2) 始终返回 true（值相等）。

int x = value;
x == y
基本类型 int 的比较始终基于值，因此 x == y 始终返回 true
 */

/*
== 比较引用：对于对象类型（如 Integer），== 比较的是引用是否相同。
equals 比较值：equals 方法用于比较对象的值是否相等。
自动装箱与缓存：JVM 对 -128 到 127 范围内的 Integer 值进行了缓存，导致某些情况下引用相同。
 */